package com.meilai.project.service.system.impl;

import com.meilai.project.constant.LoginTypeEnum;
import com.meilai.project.dto.app.MobileLoginDTO;
import com.meilai.project.dto.app.SignInParamForApp;
import com.meilai.project.dto.system.SignInParam;
import com.meilai.project.entity.system.User;
import com.meilai.project.entity.system.UserLoginLog;
import com.meilai.project.service.system.LoginService;
import com.meilai.project.service.system.UserLoginLogService;
import com.meilai.project.service.system.UserService;
import com.meilai.project.util.IPUtils;
import com.meilai.project.util.ThreadLocalUserUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Calendar;

/**
 * @author 张驰
 * @date 2020/12/4 15:27
 */
@Service
@Log4j2
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserService userService;

    @Autowired
    private UserLoginLogService userLoginLogService;

    /**
     * 生成登录统一返回对象
     *
     * @param token
     * @param tokenType
     */
    private SignInParam generateSignInParam(String token, String... tokenType) {
        SignInParam signInParam = new SignInParam();
        signInParam.setToken_type(tokenType.length == 1 && tokenType[0] != null ? tokenType[0] : "Bearer");
        //获取当前时间
        Timestamp now = new Timestamp(System.currentTimeMillis());
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        c.add(Calendar.MONTH, 1); //  加一个月
        Timestamp t = new Timestamp(c.getTimeInMillis());

        signInParam.setExpires_at(t);
        signInParam.setAccess_token(token);
        return signInParam;
    }

    /**
     * 记录登录
     *
     * @param ip
     * @param token
     * @param type  1：小程序，2：网页，3：app
     */
    private SignInParam saveLoginLog(String ip, String token, Integer type) {
        SignInParam signInParam = generateSignInParam(token);

        Timestamp now = new Timestamp(System.currentTimeMillis());

        // 用户id
        Long userId = ThreadLocalUserUtil.get().getId();
        // 加入用户id
        signInParam.setUser_id(userId);
        // 修改用户的最近登录时间和类型
        User u = new User();
        u.setId(userId);
        u.setLast_login(now.toLocalDateTime());
        u.setLast_login_type(type);
        userService.updateById(u);

        // 插入登录日志
        UserLoginLog loginLog = new UserLoginLog();
        loginLog.setUser_id(userId);
        loginLog.setIp(ip);
        loginLog.setLogin_at(now.toLocalDateTime());
        loginLog.setType(type);
        userLoginLogService.save(loginLog);

        return signInParam;
    }

    @Override
    @Transactional
    public SignInParam miniLogin(HttpServletRequest request, String username, String password) {
        String token = userService.signIn(request, username, password);
        return saveLoginLog(IPUtils.getIPAddress(request), token, LoginTypeEnum.MINI.getId());
    }

    @Override
    @Transactional
    public SignInParam webLogin(HttpServletRequest request, String username, String password) {
        String token = userService.signIn(request, username, password);
        return saveLoginLog(IPUtils.getIPAddress(request), token, LoginTypeEnum.WEB.getId());
    }

    @Override
    @Transactional
    public SignInParam webLoginByMobile(HttpServletRequest request, String mobile, String code) {
        String token = userService.signInByMobile(request, mobile, code);
        return saveLoginLog(IPUtils.getIPAddress(request), token, LoginTypeEnum.WEB.getId());
    }

    @Override
    @Transactional
    public SignInParamForApp appLogin(HttpServletRequest request, MobileLoginDTO dto) {
        String token = userService.signInByMobileForApp(request, dto.getMobile(), dto.getCode());
        SignInParam sip = saveLoginLog(IPUtils.getIPAddress(request), token, LoginTypeEnum.APP.getId());

        SignInParamForApp sipfa = new SignInParamForApp();
        BeanUtils.copyProperties(sip, sipfa);
        sipfa.setMobile(dto.getMobile());
        Long id = ThreadLocalUserUtil.get().getId();
        sipfa.setType(userService.getUserTypeForApp(id));
        return sipfa;
    }
}
